package it.interazionemultimodale.twitterrecognizer.ui;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import com.markupartist.android.widget.PullToRefreshListView;

import it.interazionemultimodale.twitterrecognizer.R;
import it.interazionemultimodale.twitterrecognizer.twitterutility.TweetInfo;
import it.interazionemultimodale.twitterrecognizer.twitterutility.TwitterManager;
import it.interazionemultimodale.twitterrecognizer.utility.Methods;
import it.interazionemultimodale.twitterrecognizer.utility.Variables;
import it.multimodale.twitterrecognizer.speechutility.SpeechListener;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.AnimationDrawable;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;

public class HomeActivity extends Activity
{
	//A simple Dialog redefinition that implements a personal onBackPressed, show and dismiss methods
	private class SpeechDialog extends Dialog
	{
		private ImageView imageView = null;
		private AnimationDrawable animation = null;
		
		public SpeechDialog(Context context)
		{
			super(context);
			this.requestWindowFeature(Window.FEATURE_NO_TITLE);
			this.setContentView(R.layout.speech_dialog);
			this.setCancelable(false);
			this.imageView = (ImageView)this.findViewById(R.id.micImageView);
			this.imageView.setBackgroundResource(R.anim.mic_dialog_anim);
			this.animation = (AnimationDrawable)this.imageView.getBackground();
		}
		
		@Override
		public void show()
		{
			super.show();
			animation.start();
		}
		
		@Override
		public void dismiss()
		{
			this.animation.stop();
			super.dismiss();
		}
		
		@Override
		public void onBackPressed()
		{
			Variables.speechRecognizer.stopListening();
			Variables.textToSpeech.stop();
			super.onBackPressed();
			super.dismiss();
		}
	}
	
	//A simple ProgressDialog redefinition that implements a personal onBackPressed method
	private class TweetProgressDialog extends ProgressDialog
	{
		public TweetProgressDialog(Context context)
		{
			super(context);
		}
		
		@Override
		public void onBackPressed()
		{
			Variables.speechRecognizer.stopListening();
			Variables.textToSpeech.stop();
			super.onBackPressed();
			super.dismiss();
		}
	}
	
	/*
	 * Note: these should not be here although they're gui components or gui managers, 
	 * because they're taken from R.java class.
	 * However it's a naive solution to use them into anonymous classes, and to
	 * make the code easier.
	 */
	private PullToRefreshListView tweetListView;
	private TweetAdapter listViewAdapter;
	private SpeechDialog dialog;
	private TweetProgressDialog progressDialog;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_home);
				
		//Forces screen to stay enabled
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		
		// Starting to set twitter list view (where tweets are visualized)
		this.tweetListView = (PullToRefreshListView)findViewById(R.id.tweetView);
			
		//Creates new adapter to add to tweetlistView. It will be assigned later by downloadAndVisualizeTweets method into TwitterManager
		this.listViewAdapter = new TweetAdapter(this, R.layout.riga_lista_home);
		
		//Creates and adds a footer view to tweetListView
		final View footerView = ((LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer, null, false);
		
		tweetListView.addFooterView(footerView);
		
		//Setting listener to pull list motion. This calls the routine to load new tweets
		this.tweetListView.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener()
		{
			@Override
			public void onRefresh()
			{
				TwitterManager.downloadAndVisualizeTweets(HomeActivity.this, listViewAdapter, null, Variables.TwitterTaskCommand.NEW_TWEETS, false);
			}
		});
		
		//Setting listener to each item of tweetListView (footerView included)
		this.tweetListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int position, long id)
			{
				//if (view.equals(footerView))
					//TwitterManager.downloadAndVisualizeTweets(tweetListView, listViewAdapter, null, Variables.TwitterTaskCommand.OLDER_TWEETS);
				if (!view.equals(footerView))//else
				{
					TweetInfo tweetInfo = (TweetInfo) listViewAdapter.getItem(position - 1);
					Methods.readTweetAloud(Variables.textToSpeech, tweetInfo);
				}
			}
		});
		
		//Setting listener to footerView. When it's shown while scrolling, old tweets are loaded
		this.tweetListView.setOnScrollListener(new AbsListView.OnScrollListener()
		{
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && footerView.isShown())
				{
					enableFooterProgressBar();
					TwitterManager.downloadAndVisualizeTweets(HomeActivity.this, listViewAdapter, null, Variables.TwitterTaskCommand.OLDER_TWEETS, false);
				}
			}
			
			@Override
			public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}
		});
		
		/*
		 * Creates a SpeechListener that extends and implements
		 * UtteranceProgressListener and RecognitionListener used by SpeechRecognition
		 * and TextToSpeech both.
		 */
		SpeechListener listener = new SpeechListener(this, this.tweetListView, this.listViewAdapter);
		
		//Creates and initializes a speech recognizer system
		Variables.speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
	    Variables.speechRecognizer.setRecognitionListener(listener);
	    Variables.ttsListenersMapAsk = new HashMap<String, String>();
	    
	    //Creates and initializes a tts (TextToSpeech) system
	    Variables.textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener()
	    {
			@Override
			public void onInit(int status)
			{
				if (status == TextToSpeech.SUCCESS)
				{
					int error = Variables.textToSpeech.setLanguage(Locale.ITALY);
					if (error == TextToSpeech.LANG_MISSING_DATA || error == TextToSpeech.LANG_NOT_SUPPORTED)
						System.out.println("Errore: lingua di sistema non supportata");
				}
			}
		});
		Variables.textToSpeech.setOnUtteranceProgressListener(listener);
		
		//Setting a dialog used into this activity on speech events
		this.dialog = new SpeechDialog(this);
		
		//Setting a progressDialog used during tweet reading
		this.progressDialog = new TweetProgressDialog(this);
		this.progressDialog.setIndeterminate(true);
		this.progressDialog.setCancelable(false);
		
		//Launching first tweets download and visualization
		TwitterManager.downloadAndVisualizeTweets(this, this.listViewAdapter, null, Variables.TwitterTaskCommand.HOME_TWEETS, false);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		//Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.home, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		// Handle item selection
		switch (item.getItemId()) 
		{
			case R.id.logout:
				CookieSyncManager.createInstance(this);
				CookieManager cookieManager = CookieManager.getInstance();
				cookieManager.removeSessionCookie();
				
				Editor e = Variables.mSharedPreferences.edit();
				e.remove(Variables.KEY_OAUTH_TOKEN);
				e.remove(Variables.KEY_OAUTH_SECRET);
				e.remove(Variables.KEY_TWITTER_LOGIN);
				e.commit();
				
				Intent intent = new Intent(this, MainActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
				this.startActivity(intent);
				this.finish();
				
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}
	
	@Override
	protected void onDestroy()
	{
		Variables.speechRecognizer.destroy();
		Variables.textToSpeech.stop();
		Variables.textToSpeech.shutdown();
		super.onDestroy();
	}
	
	//Speech button listener
	public void startSpeechRecognition(View view)
	{
		this.disableButtons();
		this.showSpeechDialog();
	    Variables.textToSpeech.stop();
		Variables.speechRecognizer.startListening(Methods.getSpeechRecognizerIntent());
	}
	
	//Gesture button listener
	public void startGestureRecognition(View view)
	{
		this.startActivityForResult(new Intent(this, GestureActivity.class), 1);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		if (requestCode == 1 && resultCode == Activity.RESULT_OK)
		{
			int tweetsNumber = data.getIntExtra("tweets_number", -1);
			
			if (tweetsNumber < 0)	//ERROR
				return;
			else if (tweetsNumber == 0)		//Load new tweets
				TwitterManager.downloadAndVisualizeTweets(this, this.listViewAdapter, null, Variables.TwitterTaskCommand.NEW_TWEETS, true);
			else
			{
				List<TweetInfo> tweets = this.listViewAdapter.getFirstNItems(tweetsNumber);
				this.progressDialog.setMessage("Caricamento...");
				this.progressDialog.show();
				Methods.readTweetsAloud(Variables.textToSpeech, Variables.ttsListenersMapAsk, tweets);
			}
		}
	}
	
	public void setListAdapter(TweetAdapter adapter)
	{
		this.tweetListView.setAdapter(adapter);
	}
	
	//Comunicates to tweetListView that loading of new tweets is ended
	public void listViewRefreshCompleted()
	{
		this.tweetListView.onRefreshComplete();
	}
	
	public List<TweetInfo> getTweets(int tweetNumber)
	{
		return this.listViewAdapter.getFirstNItems(tweetNumber);
	}
	
	public void downloadAndVisualizeTweets(Variables.TwitterTaskCommand command)
	{
		if (command == Variables.TwitterTaskCommand.NEW_TWEETS)
			this.runOnUiThread(new Runnable()
			{
				@Override
				public void run() {
					TwitterManager.downloadAndVisualizeTweets(HomeActivity.this, listViewAdapter, Variables.textToSpeech, Variables.TwitterTaskCommand.NEW_TWEETS, true);
				}
			});
		else if (command == Variables.TwitterTaskCommand.OLDER_TWEETS)
			this.runOnUiThread(new Runnable()
			{
				@Override
				public void run() {
					TwitterManager.downloadAndVisualizeTweets(HomeActivity.this, listViewAdapter, Variables.textToSpeech, Variables.TwitterTaskCommand.OLDER_TWEETS, true);
				}
			});
	}
	
	public void enableButtons()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				((Button)findViewById(R.id.buttonListen)).setEnabled(true);
				((Button)findViewById(R.id.buttonGesture)).setEnabled(true);
			}
		});
	}
	
	public void disableButtons()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				((Button)findViewById(R.id.buttonListen)).setEnabled(false);
				((Button)findViewById(R.id.buttonGesture)).setEnabled(false);
			}
		});
	}
	
	public void disableHomeProgressBar()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				((ProgressBar)findViewById(R.id.homeProgressBar)).setVisibility(View.GONE);
			}
		});
	}
	
	public void enableListView()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				tweetListView.setVisibility(View.VISIBLE);
			}
		});
	}
	
	public void enableFooterProgressBar()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				((ProgressBar)findViewById(R.id.footerProgressBar)).setVisibility(View.VISIBLE);
			}
		});
	}
	
	public void disableFooterProgressBar()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				((ProgressBar)findViewById(R.id.footerProgressBar)).setVisibility(View.INVISIBLE);
			}
		});
	}
	
	public void showSpeechDialog()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				dialog.show();
			}
		});
	}
	
	public void dismissSpeechDialog()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				dialog.dismiss();
			}
		});
	}
	
	public void showTweetProgressDialog()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				progressDialog.show();
			}
		});
	}
	
	public void setTweetProgressBarMessage(final String text)
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				progressDialog.setMessage(text);
			}
		});
	}
	
	public void dismissTweetProgressDialog()
	{
		this.runOnUiThread(new Runnable()
		{
			@Override
			public void run() {
				progressDialog.dismiss();
			}
		});
	}
}
